package com.example.hospitalManage.controller.user.api;

import com.example.hospitalManage.common.Constant;
import com.example.hospitalManage.common.ServiceResultEnum;
import com.example.hospitalManage.config.annotation.TokenToNormalUser;
import com.example.hospitalManage.controller.user.param.UserDetail;
import com.example.hospitalManage.controller.user.param.UserLoginParam;
import com.example.hospitalManage.controller.user.param.UserRegisterParam;
import com.example.hospitalManage.controller.user.param.UserUpdateParam;
import com.example.hospitalManage.entity.UserInfo;
import com.example.hospitalManage.service.UserInfoService;
import com.example.hospitalManage.service.UserOperateService;
import com.example.hospitalManage.utils.BeanUtil;
import com.example.hospitalManage.utils.NumberUtil;
import com.example.hospitalManage.utils.Response;
import com.example.hospitalManage.utils.ResponseResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @ProjectName: yygh
 * @Author: gxy
 * @Time: 2022/12/21 15:57
 * @Description: 用户的个人操作：登录、注册等
 */

@RestController
@Api(value = "v1",tags = "医院挂号用户操作相关接口")
@RequestMapping("/api")
public class UserOperateController {

    @Resource
    private UserOperateService userOperateService;

    @Autowired
    UserInfoService userInfoService;

    private static final Logger logger = LoggerFactory.getLogger(UserOperateController.class);

    @PostMapping("/user/login")
    @ApiOperation(value = "登录接口", notes = "返回token")
    public ResponseResult<String> login(@RequestBody @Valid UserLoginParam userLoginParam) {
        if (!NumberUtil.isPhone(userLoginParam.getPhone())){
            return Response.createFailResp(ServiceResultEnum.LOGIN_NAME_IS_NOT_PHONE.getResult());
        }
        String loginResult = userOperateService.login(userLoginParam.getPhone(), userLoginParam.getPasswordMd5());

        logger.info("login api,loginPhone={},loginResult={}", userLoginParam.getPhone(), loginResult);

        //登录成功
        if (!StringUtils.isEmpty(loginResult) && loginResult.length() == Constant.TOKEN_LENGTH) {
            return Response.createOkResp("登陆成功",loginResult);
        }
        //登录失败
        return Response.createFailResp(loginResult);

        /**
         * @param userLoginParam:
         * @return ResponseResult<String>
         * @author GCT
         * @description TODO
         * 权限管理登录
         * @date 2023/1/2 22:16
         */
//        //1.获取当前的 Subject. 调用 SecurityUtils.getSubject();
//        Subject subject = SecurityUtils.getSubject();
//        //2.创建登录令牌,存储了用户名和密码，这个token是shiro创建的，也可以使用 jwt token
////        UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(phone,password);
//        UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(userLoginParam.getPhone(),userLoginParam.getPasswordMd5());
//        System.out.println("token:"+usernamePasswordToken);
//
////        Msg msg=null;
////        ResponseResult<String> rsep = null;
//        //3.登录判断
//        try {
//            // 3.1调用shiro的login方法进行登录判断
//            subject.login(usernamePasswordToken);
//            //将token返回给前端
////            msg=Msg.success("登录成功").add("token",subject.getSession().getId());
//            return Response.createOkResp("登录成功", "token:" + subject.getSession().getId());
//        } catch (Exception  e) {
////            msg = Msg.fail("账号出错或密码出错");
//            return Response.createFailResp("账号出错或密码出错");
//        }
////        return rsep;
    }

    @PostMapping("/user/shiroLogin")
    @ApiOperation(value = "shiro登录接口", notes = "返回token")
    public ResponseResult<String> shiroLogin(@RequestBody @Valid UserLoginParam userLoginParam) {
        if (!NumberUtil.isPhone(userLoginParam.getPhone())){
            return Response.createFailResp(ServiceResultEnum.LOGIN_NAME_IS_NOT_PHONE.getResult());
        }
//        String loginResult = userOperateService.login(userLoginParam.getPhone(), userLoginParam.getPasswordMd5());
//
//        logger.info("login api,loginPhone={},loginResult={}", userLoginParam.getPhone(), loginResult);
//
//        //登录成功
//        if (!StringUtils.isEmpty(loginResult) && loginResult.length() == Constant.TOKEN_LENGTH) {
//            return Response.createOkResp("登陆成功",loginResult);
//        }
//        //登录失败
//        return Response.createFailResp(loginResult);

        /**
         * @param userLoginParam:
         * @return ResponseResult<String>
         * @author GCT
         * @description TODO
         * 权限管理登录
         * @date 2023/1/2 22:16
         */
        //1.获取当前的 Subject. 调用 SecurityUtils.getSubject();
        Subject subject = SecurityUtils.getSubject();
        //2.创建登录令牌,存储了用户名和密码，这个token是shiro创建的，也可以使用 jwt token
//        UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(phone,password);
        UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(userLoginParam.getPhone(),userLoginParam.getPasswordMd5());
        System.out.println("token:"+usernamePasswordToken);

//        Msg msg=null;
//        ResponseResult<String> rsep = null;
        //3.登录判断
        try {
            // 3.1调用shiro的login方法进行登录判断
            subject.login(usernamePasswordToken);
            //将token返回给前端
//            msg=Msg.success("登录成功").add("token",subject.getSession().getId());
            return Response.createOkResp("登录成功", "token:" + subject.getSession().getId());
        } catch (Exception  e) {
//            msg = Msg.fail("账号出错或密码出错");
            return Response.createFailResp("账号出错或密码出错");
        }
//        return rsep;
    }


    @PostMapping("/user/logout")
    @ApiOperation(value = "登出接口", notes = "清除token")
    public ResponseResult<String> logout(@TokenToNormalUser UserInfo userInfo) {
        Boolean logoutResult = userOperateService.logout(userInfo.getId());

        logger.info("logout api,loginUser={}", userInfo.getId());

        //登出成功
        if (logoutResult) {
            return Response.createOkResp("退出登录成功");
        }
        //登出失败
        return Response.createFailResp("退出登录失败");
    }


    @PostMapping("/user/register")
    @ApiOperation(value = "用户注册", notes = "")
    public ResponseResult register(@RequestBody @Valid UserRegisterParam userRegisterParam) {
        if (!NumberUtil.isPhone(userRegisterParam.getPhone())){
            return Response.createFailResp(ServiceResultEnum.LOGIN_NAME_IS_NOT_PHONE.getResult());
        }
        String registerResult = userOperateService.register(userRegisterParam.getNickName(),
                userRegisterParam.getPasswordMd5(),userRegisterParam.getPhone(), userRegisterParam.getRealName());

        logger.info("register api,phone={},loginResult={}", userRegisterParam.getPhone(), registerResult);

        //注册成功
        if (ServiceResultEnum.SUCCESS.getResult().equals(registerResult)) {
            return Response.createOkResp();
        }
        //注册失败
        return Response.createFailResp(registerResult);
    }

    @PutMapping("/user/info")
    @ApiOperation(value = "修改用户信息", notes = "")
    public ResponseResult updateInfo(@RequestBody @ApiParam("用户信息") UserUpdateParam userUpdateParam, @TokenToNormalUser UserInfo userInfo) {
        Boolean flag = userOperateService.updateUserInfo(userInfo.getId(),userUpdateParam);
        if (flag) {
            //返回成功
            return Response.createOkResp("修改成功");
        } else {
            //返回失败
            return Response.createFailResp("修改失败");
        }
    }

    @GetMapping("/user/info")
    @ApiOperation(value = "获取用户信息", notes = "")
    public ResponseResult<UserDetail> getUserDetail(@TokenToNormalUser UserInfo userInfo) {
        //已登录则直接返回
        UserDetail userDetail = new UserDetail();
        BeanUtil.copyProperties(userInfo, userDetail);
        return Response.createOkResp(userDetail);
    }

}
